依赖关系预捆绑
当您第一次进行投票时，您可能会注意到以下消息：
检测到优化的依存关系：
react, react-dom
预捆绑它们以加快开发服务器页面加载速度...
（仅当您的依赖项已更改时才运行）


为什么
Vite正在执行我们所谓的“依赖关系预捆绑”。 此过程有两个目的：
1.CommonJS和UMD兼容性：在开发过程中，Vite的开发人员将所有代
码用作本机ESM。 因此，Vite必须首先将以CommonJS或UMD形式提
供的依赖项转换为ESM。
转换CommonJS依赖项时，Vite会执行智能导入分析，以便即使动态
分配了导出（例如React），对CommonJS模块的命名导入也可以按预期工作：
// 按预期工作
import React, { useState } from 'react'
2.性能：Vite将带有许多内部模块的ESM依赖关系转换为单个模块，
以提高后续页面加载性能。
某些软件包附带了其ES模块，因为它们相互之间导入了许多单独的文件。
例如，lodash-es有600多个内部模块！ 当我们
从“ lodash-es”导入{debounce}时，浏览器会同时触发600多
个HTTP请求！ 即使服务器在处理它们时没有问题，大量请求也会在
浏览器端造成网络拥塞，从而导致页面加载明显变慢。
通过将lodash-es预先捆绑到一个模块中，现在我们只需要一个HTTP请求即可！




自动依赖发现
如果找不到现有的缓存，Vite将抓取您的源代码并自动发现依赖项
导入（即，期望从node_modules解决的“裸导入”），并将这些找
到的导入用作预捆绑的入口点。 预捆绑是通过esbuild执行的，因此通常非常快。
服务器启动后，如果遇到新的依赖项导入（尚未在缓存中），
则Vite将重新运行dep捆绑过程并重新加载页面。




Monorepos和链接的依赖项
在monorepo设置中，依赖项可能是来自同一存储库的链接包。 Vite自动
检测到未从node_modules解决的依赖关系，并将链接的dep视为源代码。 
它不会尝试捆绑链接的dep，而是将分析链接的dep的依赖项列表。



自定义行为
默认的依赖项发现试探法可能并不总是令人满意的。 如果要从列表中明确
包含/排除依赖关系，请使用optimizeDeps配置选项。
对于optimizeDeps.include或optimizeDeps.exclude，典型的用例是在
源代码中无法直接发现导入的情况下。 例如，也许导入是由于插件转换而创
建的。 这意味着Vite将无法在初始扫描中发现导入-只能在浏览器请求并转换
文件后才发现导入。 这将导致服务器在服务器启动后立即重新捆绑。
包含和排除均可用于处理此问题。 如果依赖关系很大（有许多内部模块）或
是CommonJS，则应包括它； 如果依赖性很小并且已经是有效的ESM，
则可以将其排除，然后让浏览器直接加载它。




Caching
1.文件系统缓存
Vite将预先捆绑的依赖项缓存在node_modules / .vite中。 它根据一
些来源确定是否需要重新运行预捆绑步骤：
package.json中的依赖项列表
软件包管理器锁定文件，例如 package-lock.json，yarn.lock或pnpm-lock.yaml。
vite.config.js中的相关字段（如果存在）。
仅在上述情况之一发生更改时，才需要重新运行预捆绑步骤。
如果出于某种原因要强制Vite重新捆绑Dep，则可以使用--force命令行选项启动
开发服务器，也可以手动删除node_modules / .vite缓存目录。
2.浏览器缓存
已解决的依赖项请求使用HTTP标头max-age = 31536000进行了强烈缓存，
不可更改，以提高开发期间的页面重新加载性能。 一旦被缓存，这些请求
将永远不会再次到达开发服务器。 如果安装了其他版本，则附加的版本查
询会自动使它们无效（如软件包管理器锁定文件中所示）。 如果要通过
进行本地编辑来调试依赖项，则可以：
通过浏览器devtools的“网络”选项卡临时禁用缓存；
用--force标志重新启动Vite开发服务器以重新捆绑部门；
重新加载页面。